package com.oner365.test.zip;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.jsoup.Jsoup;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;

import net.dongliu.apk.parser.ApkFile;
import net.dongliu.apk.parser.bean.ApkMeta;

public class APKExtractor {

  public static void main(String[] args) {
    String outputDir = "/Users/taoliu/Downloads/unzipNew/";
    String apkPath = "/Users/taoliu/Downloads/test.apk";
//    unZipApk(apkPath, outputDir);
//    parserDom(outputDir);
//    parserSAX(outputDir);
    parserJsoup(outputDir);
    apkParser(apkPath);
  }

  public static void unZipApk(String apkPath, String outputDir) {
    try (FileInputStream fis = new FileInputStream(apkPath); ZipInputStream zis = new ZipInputStream(fis);) {
      ZipEntry zipEntry;
      while ((zipEntry = zis.getNextEntry()) != null) {
        File file = new File(outputDir, zipEntry.getName());
        if (zipEntry.isDirectory()) {
          file.mkdirs();
        } else {
          new File(file.getParent()).mkdirs();
          try (FileOutputStream fos = new FileOutputStream(file)) {
            byte[] buffer = new byte[1024];
            int len;
            while ((len = zis.read(buffer)) > 0) {
              fos.write(buffer, 0, len);
            }
          }
        }
        zis.closeEntry();
      }
      zis.close();
    } catch (FileNotFoundException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  public static void parserDom(String outputDir) {
    try {
      File xmlFile = new File(outputDir + "AndroidManifest.xml");
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      DocumentBuilder builder = factory.newDocumentBuilder();
      Document document = builder.parse(xmlFile);
      document.getDocumentElement().normalize();

      System.out.println("Root element: " + document.getDocumentElement().getNodeName());

      NodeList nodeList = document.getElementsByTagName("manifest");
      for (int i = 0; i < nodeList.getLength(); i++) {
        Node node = nodeList.item(i);
        if (node.getNodeType() == Node.ELEMENT_NODE) {
          Element element = (Element) node;
          System.out.println("dom Package: " + element.getAttribute("package"));
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public static void parserSAX(String outputDir) {
    try {
      SAXParserFactory factory = SAXParserFactory.newInstance();
      SAXParser saxParser = factory.newSAXParser();

      DefaultHandler handler = new DefaultHandler() {
        boolean isPackage = false;

        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) {
          if (qName.equalsIgnoreCase("manifest")) {
            isPackage = true;
          }
        }

        @Override
        public void endElement(String uri, String localName, String qName) {
          // 结束元素时的处理
        }

        @Override
        public void characters(char ch[], int start, int length) {
          if (isPackage) {
            System.out.println("sax Package: " + new String(ch, start, length));
            isPackage = false; // 读取后重置
          }
        }
      };

      saxParser.parse(outputDir + "AndroidManifest.xml", handler);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public static void parserJsoup(String outputDir) {
    try {
      File input = new File(outputDir + "AndroidManifest.xml");
      org.jsoup.nodes.Document doc = Jsoup.parse(input, "UTF-8");
      String packageName = doc.select("manifest").attr("package");
      System.out.println("jsoup Package: " + packageName);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  
  public static void apkParser(String apkPath) {
    try(ApkFile apkFile = new ApkFile(apkPath)){
      ApkMeta apkMeta = apkFile.getApkMeta();
      System.out.println(apkMeta.getVersionName());
      System.out.println(apkMeta.getVersionCode());
      System.out.println(apkMeta.getPackageName());
      System.out.println(apkMeta.getName());
      System.out.println(apkFile.getAllIcons());
    } catch (IOException e) {
      e.printStackTrace();
    } 
  }

}
